package com.xyy.saas.payment.callback.core.service;

import com.jddglobal.open.client.DefaultSpiJddClient;
import com.jddglobal.open.response.base.SpiResponse;
import com.jddglobal.open.support.config.EsuSdkConfig;
import com.jddglobal.open.support.util.JacksonUtils;
import com.xyy.saas.payment.adpater.fumin.config.SDKVersion;
import com.xyy.saas.payment.adpater.jdCredit.enums.CodeEnum;
import com.xyy.saas.payment.adpater.jdCredit.resp.ApiResponse;
import com.xyy.saas.payment.adpater.jdCredit.support.JdCreditClientFactory;
import com.xyy.saas.payment.adpater.jdCredit.util.DateUtil;
import com.xyy.saas.payment.common.Constants;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.cores.enums.ResultCodeEnum;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author wangtianqi
 * @date 2020/3/19 14:59
 */
public class CallbackResponseAdapterService {
    private static final String SPI_CODE = "00000";
    private ConcurrentHashMap<String, Method> concurrentHashMap = new ConcurrentHashMap();

    public CallbackResponseAdapterService() throws ClassNotFoundException {
        // Construction method
    }

    public String wx(Boolean success, HttpServletResponse response, String version) {
        if(success) {
            return Constants.WX_CALLBACK_SUCCESS;
        }

        return Constants.WX_CALLBACK_FAIL;
    }

    public String alipay(Boolean success, HttpServletResponse response, String version) {
        if(success) {
            return Constants.ALI_CALLBACK_SUCCESS;
        }

        return Constants.ALI_CALLBACK_FAIL;
    }


    public String directwx(Boolean success, HttpServletResponse response, String version) {
        if(success) {
            return Constants.WX_CALLBACK_SUCCESS;
        }

        return Constants.WX_CALLBACK_FAIL;
    }

    public String directalipay(Boolean success, HttpServletResponse response, String version) {
        if(success) {
            return Constants.ALI_CALLBACK_SUCCESS;
        }

        return Constants.ALI_CALLBACK_FAIL;
    }

    public String jd_card(Boolean success, HttpServletResponse response, String version) {
        if (success) {
            response.setStatus(200);
            return Constants.JD_CALLBACK_SUCCESS;
        }
        response.setStatus(500);
        return Constants.JD_CALLBACK_FAIL;
    }

    public String jdaggregate(Boolean success, HttpServletResponse response, String version) {
        if (success) {
            response.setStatus(200);
            return Constants.JDAGGREGATE_CALLBACK_SUCCESS;
        }
        response.setStatus(500);
        return Constants.JDAGGREGATE_CALLBACK_ERROR;
    }
    public String jd_credit(Boolean success, HttpServletRequest request, HttpServletResponse response, String version) throws Exception {
        DefaultSpiJddClient defaultSpiJddClient = JdCreditClientFactory.getDefaultSpiJddClient();
        //返回参数封装
        ApiResponse apiResponse = new  ApiResponse();
        apiResponse.setReqNo(DateUtil.formatDateString(new Date(), DateUtil.DATEPATTERN));
        apiResponse.setResDate(DateUtil.formatDateString(new Date(), DateUtil.DATEPATTERN));
        //如果有返回数据
        Map<String, Object> res = new HashMap<>();
        //res.put("key1", "value1");
        apiResponse.setData(res);
        if (success) {
            //成功
            apiResponse.setResCode(CodeEnum.SUCCESS.getCode());
            apiResponse.setResDesc(CodeEnum.SUCCESS.getMsg());
        } else {
            //失败
            apiResponse.setResCode(CodeEnum.FAIL.getCode());
            apiResponse.setResDesc(CodeEnum.FAIL.getMsg());
        }


        //TODO 失败用哪个码
        SpiResponse spiResponse = new SpiResponse(SPI_CODE, "成功",
                DateUtil.formatDateString(new Date(), DateUtil.DATEPATTERN),
                JacksonUtils.toJson(apiResponse));
        String body = defaultSpiJddClient.callback(request, response, spiResponse);
        //获得字符输出流
        response.setCharacterEncoding("utf-8");
        //TODO 怎么是用流
        PrintWriter writer = response.getWriter();
        writer.write(body);
        return body;
    }
    public String pingxx(Boolean success, HttpServletResponse response, String version) {
        if(success) {
            response.setStatus(200);
            return Constants.PINGXX_CALLBACK_SUCCESS;
        }

        response.setStatus(500);
        return Constants.PINGXX_CALLBACK_FAIL;
    }

    public String chinabank(Boolean success, HttpServletResponse response, String version) {
        if(success) {
            return Constants.CHINABANK_CALLBACK_SUCCESS;
        }

        return Constants.CHINABANK_CALLBACK_FAIL;
    }

    public String fm(Boolean success, HttpServletResponse response, String version) {
        if(success) {
            return SDKVersion.SDK_VERSION_V2.equals(version) ? Constants.FBANK_CALLBACK_SUCCESS_V2 : Constants.CHINABANK_CALLBACK_SUCCESS;
        }

        return SDKVersion.SDK_VERSION_V2.equals(version) ? Constants.FBANK_CALLBACK_FAIL_V2 : Constants.CHINABANK_CALLBACK_FAIL;
    }

    public String unionpay(Boolean success, HttpServletResponse response, String version) {
        if(success) {
            return Constants.UNIONPAY_CALLBACK_SUCCESS;
        }

        return Constants.UNIONPAY_CALLBACK_FAIL;
    }

    public String ybmfm(Boolean success, HttpServletResponse response, String version) {
        if(success) {
            return SDKVersion.SDK_VERSION_V2.equals(version) ? Constants.FBANK_CALLBACK_SUCCESS_V2 : Constants.FBANK_CALLBACK_SUCCESS;
        }

        return SDKVersion.SDK_VERSION_V2.equals(version) ? Constants.FBANK_CALLBACK_FAIL_V2 : Constants.FBANK_CALLBACK_FAIL;
    }

    public String yop(Boolean success, HttpServletResponse response, String version) {
        if(success) {
            return Constants.FBANK_CALLBACK_SUCCESS_V2;
        }

        return Constants.FBANK_CALLBACK_FAIL_V2;
    }

    public String pingan(Boolean success, HttpServletResponse response, String version) {
        if(success) {
            return Constants.PINGAN_CALLBACK_SUCCESS;
        }

        return Constants.PINGAN_CALLBACK_FAIL;
    }

    private Class callbackResponseAdapterServiceClass = Class.forName("com.xyy.saas.payment.callback.core.service.CallbackResponseAdapterService");

    public String invoker(String methodName, Boolean success, HttpServletResponse response, String version) throws Exception {
        Method method = concurrentHashMap.get(methodName);

        if(method == null) {
            method = callbackResponseAdapterServiceClass.getMethod(methodName, Boolean.class, HttpServletResponse.class, String.class);

            if(method == null) {
                throw new PaymentException(ResultCodeEnum.UN_SUPPORT_METHOD);
            }

            concurrentHashMap.put(methodName, method);
        }

        return (String) method.invoke(getInstance(), success, response, version);
    }

    public static CallbackResponseAdapterService getInstance() {
        return CallbackResponseAdapterService.MyCallbackResponseAdapterService.instance;
    }

    /**
     * 内部类
     */
    private static class MyCallbackResponseAdapterService {
        private static CallbackResponseAdapterService instance;

        static {
            try {
                instance = new CallbackResponseAdapterService();
            }
            catch(ClassNotFoundException e) {
                // ignore error
            }
        }
    }
}
